package com.nowcoder.community.service;

import com.nowcoder.community.dao.AlphaDao;
import com.nowcoder.community.dao.DiscussPostMapper;
import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.util.CommunityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;

//容器管理该业务
//@Service
//管理其生命周期(默认为单例singleton)
//@Scope("prototype")//此处每次访问都新建
public class AlphaService {

    private static final Logger logger = LoggerFactory.getLogger(AlphaService.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DiscussPostMapper discussPostMapper;


    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private AlphaDao alphaDao;
//    调用
    public String find(){
        return alphaDao.select();
    }

    public AlphaService(){
        System.out.println("实例化AlphaService");
    }

//    构建后自动调用
    @PostConstruct
    public void init(){
        System.out.println("初始化AlphaService");
    }
//    销毁前调用
    @PreDestroy
    public void destroy(){
        System.out.println("销毁AlphaService");
    }

    //REQUIRED:支持当前事务（外部事务），如果不存在则创建新事务
    //REOUIRES NEW:创建一个新事务，并且暂停当前事务（外部事务）：
    //NESTED:如果当前存在事务（外部事务），则嵌套在该事务中执行（独立的提交和回滚），否则就会REQUIRED一样.
//    事务管理注解 隔离性 传播机制
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    public Object save1(){
    //新增用户
        User user = new User();
        user.setUsername("alpha");
        user.setSalt(CommunityUtil.generateUUID().substring(0,5));
        user.setPassword(CommunityUtil.md5("123"+user.getSalt()));
        user.setEmail("alpha@qq.com");
        user.setHeaderUrl("https://ui-avatars.com/api/?name=" + user.getUsername() + "&rounded=true");
        user.setCreateTime(new Date());

        userMapper.insertUser(user);

        //新增帖子
        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle("Hello");
        post.setContent("新人报道!");
        post.setCreateTime(new Date());
        discussPostMapper.insertDiscussPost(post);

        Integer.valueOf("abc");

        return "OK";
    }
//编程式实现
    public Object save2(){
    transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

    return transactionTemplate.execute(new TransactionCallback<Object>() {
        @Override
        public Object doInTransaction(TransactionStatus transactionStatus) {
            //新增用户
            User user = new User();
            user.setUsername("alpha");
            user.setSalt(CommunityUtil.generateUUID().substring(0,5));
            user.setPassword(CommunityUtil.md5("123"+user.getSalt()));
            user.setEmail("alpha@qq.com");
            user.setHeaderUrl("https://ui-avatars.com/api/?name=" + user.getUsername() + "&rounded=true");
            user.setCreateTime(new Date());

            userMapper.insertUser(user);

            //新增帖子
            DiscussPost post = new DiscussPost();
            post.setUserId(user.getId());
            post.setTitle("Hello");
            post.setContent("新人报道!");
            post.setCreateTime(new Date());
            discussPostMapper.insertDiscussPost(post);

            Integer.valueOf("abc");
            return "OK";
        }
    });
    }

    @Async //该方法在多线程的环境下会被异步调用
    public void execute1(){
        logger.debug("Spring普通线程池简化配置!");
    }

    //延迟时间 间隔
    @Scheduled(initialDelay = 10000,fixedRate = 1000) //该方法在多线程的环境下会被异步调用
    public void execute2(){
        logger.debug("Spring定时线程池简化配置!");
    }
}
